package std::collection;

import std::Object;

public class HashSet : Collection 
{
	friend class HashSetIterator;

	m_bucket->ArrayList[];
	m_size->int;
	public HashSet()
	{
		m_bucket=new ArrayList[32];
		m_size=0;
		i->int=0;
		while(i<m_bucket.length){
			m_bucket[i++]=new ArrayList();
		}
	}
	public HashSet(size->int)
	{
		size=size<=32?32:(1024<size?1024:size);
		m_bucket=new ArrayList[size];
		m_size=0;
		i->int=0;
		while(i<m_bucket.length){
			m_bucket[i++]=new ArrayList();
		}
	}
	public add(e->Object)
	{
		if(e==null)return;
		buckNum->const int=m_bucket.length;
		hashcode->int=e.hashcode();
		index->int=(hashcode%buckNum+buckNum)%buckNum;
		vec->ArrayList=m_bucket[index];
		i->int=0;
		size->int=vec.size();
		while(i<size){
			if(vec.get(i).hashcode()==hashcode){
				vec.set(i, e);
				return;
			}
			++i;
		}
		vec.add(e);
		++m_size;
	}
	
	public remove(e->Object)
	{
		if(e==null)return;
		buckNum->const int=m_bucket.length;
		hashcode->int=e.hashcode();
		index->int=(hashcode%buckNum+buckNum)%buckNum;
		vec->ArrayList=m_bucket[index];
		i->int=0;
		size->int=vec.size();
		while(i<size){
			if(vec.get(i).hashcode()==hashcode){
				vec.remove(i);
				--m_size;
				return;
			}
			++i;
		}
	}
	public exist(e->Object)->boolean
	{
		if(e==null)return false;
		buckNum->const int=m_bucket.length;
		hashcode->int=e.hashcode();
		index->int=(hashcode%buckNum+buckNum)%buckNum;
		vec->ArrayList=m_bucket[index];
		i->int=0;
		size->int=vec.size();
		while(i<size){
			if(vec.get(i).hashcode()==hashcode){
				return true;
			}
			++i;
		}
		return false;
	}
	public size()->int{return m_size;}
	public iterator()->Iterator{return new HashSetIterator(this);}
}

class HashSetIterator : Iterator
{
	m_set->HashSet;
	m_bkrow->int=0;
	m_bkcol->int=0;
	public HashSetIterator(set->HashSet){m_set=set;}
	public hasNext()->boolean
	{
		buckets->ArrayList[]=m_set.m_bucket;
		while(m_bkrow<buckets.length){
			bucket->ArrayList=buckets[m_bkrow];
			if(m_bkcol<bucket.size())return true;
			++m_bkrow;
			m_bkcol=0;
		}
		return false;
	}
	public next()->Object
	{
		buckets->ArrayList[]=m_set.m_bucket;
		if(m_bkrow<buckets.length){
			bucket->ArrayList=buckets[m_bkrow];
			if(m_bkcol<bucket.size()){
				return bucket.get(m_bkcol++);
			}
			else return null;
		}
		else return null;
	}
}

